<template>
  <div class="endless-tower">
    <div class="battle-info">
      <div class="player-info">
        <tag class="name" type="primary" @click="openInfo('player')">
          {{ player.name }}
        </tag>
        <el-progress :percentage="playerProgress" :status="playerStatus" :format="playerHealth" :stroke-width="20"
          text-inside />
      </div>
      <div class="vs">VS</div>
      <div class="monster-info" v-if="monster">
        <tag class="name" type="danger" @click="openInfo('monster')">{{ monster.name }}</tag>
        <el-progress :percentage="monsterProgress" :status="monsterStatus" :format="monsterhealth" :stroke-width="20"
          text-inside />
      </div>
    </div>
    <div class="actions">
      <el-button v-for="(item, index) in buttonData" :key="index" @click="item.click" :disabled="item.disabled">
        {{ item.text }}
      </el-button>
    </div>
    <div class="sweep-info">
      <el-row>
        <el-col :span="6" v-for="(item, index) in sweepData" :key="index">
          <div class="el-statistic">
            <div class="el-statistic__head" v-text="item.name" />
            <div class="el-statistic__content">
              <span class="el-statistic__number" v-text="item.suffix" />
            </div>
          </div>
        </el-col>
      </el-row>
    </div>
    <el-scrollbar class="battle-log" height="300px" ref="scrollbar" always>
      <p v-for="(log, index) in battleLogs" :key="index" v-html="log" />
    </el-scrollbar>
  </div>
</template>

<script setup>
// 标签组件
import tag from '@/components/tag.vue'
// boss
import boss from '@/plugins/boss'
// 装备
import equip from '@/plugins/equip'
// 怪物
import monsters from '@/plugins/monster'
import combatSystem from '@/plugins/combat'
import { ElMessageBox } from 'element-plus'
import { checkAchievements } from '@/plugins/achievementChecker'
import { useRouter } from 'vue-router'
import { ref, watch, computed, onMounted, onUnmounted } from 'vue'
import { useMainStore } from '@/plugins/store'
import { smoothScrollToBottom, formatNumberToChineseUnit, genre, levels, gameNotifys } from '@/plugins/game'

const router = useRouter()
const store = useMainStore()
// 玩家数据
const player = ref(store.player)
// 怪物数据
const monster = ref(null)
const observer = ref(null)
// 扫荡时间
const sweepTime = ref(0)
// 战斗日志
const battleLogs = ref([])
// 当前层数
const currentFloor = ref(1)
// 是否正在扫荡
const isSweeping = ref(false)
// 扫荡结果
const sweepResults = ref({
  // 获得的修为
  expGain: 0,
  // 获得的灵石
  moneyGain: 0,
  // 获得的装备数量
  equipmentGained: 0
})
// 玩家气血状态
const playerStatus = ref('success')
// 怪物气血状态
const monsterStatus = ref('success')
// 扫荡时间间隔
const sweepInterval = ref(null)
// 是否自动战斗
const isAutoFighting = ref(false)
// 自动战斗时间间隔
const autoFightInterval = ref(null)
// 扫荡战斗时间间隔
const sweepFightInterval = ref(null)
const scrollbar = ref(null)

// 扫荡相关信息
const sweepData = computed(() => {
  return [
    { name: '扫荡时间', suffix: formatTime(sweepTime.value) },
    { name: '获得修为', suffix: `${formatNumberToChineseUnit(sweepResults.value.expGain)}点` },
    { name: '获得灵石', suffix: `${formatNumberToChineseUnit(sweepResults.value.moneyGain)}块` },
    { name: '获得装备', suffix: `${formatNumberToChineseUnit(sweepResults.value.equipmentGained)}件` },
  ]
})

// 按钮
const buttonData = computed(() => {
  return [
    { text: isAutoFighting.value ? '停止对战' : '自动对战', click: () => toggleAutoFight(), disabled: isSweeping.value || player.value.health <= 0 },
    { text: '进行对战', click: () => fight(), disabled: isSweeping.value || isAutoFighting.value || !monster.value || player.value.health <= 0 },
    { text: isSweeping.value ? '停止扫荡' : '开始扫荡', click: () => toggleSweep(), disabled: isAutoFighting.value || player.value.health <= 0 },
    { text: '撤退回家', click: () => retreat(), disabled: false }
  ]
})

// 玩家血量进度条
const playerProgress = computed(() => {
  return (player.value.health / player.value.maxHealth) * 100
})

// 怪物血量进度条
const monsterProgress = computed(() => {
  return (monster.value.health / monster.value.maxHealth) * 100
})

// 监听battleLogs变化
watch(() => battleLogs.value, () => setupObserver(), {
  deep: true
})

// 监听玩家血量变化
watch(() => player.value.health, () => {
  const { health, maxHealth } = player.value
  playerStatus.value = getStatus(health, maxHealth)
})

// 监听怪物血量变化
watch(() => monster.value?.health, () => {
  if (monster.value) {
    const { health, maxHealth } = monster.value
    monsterStatus.value = getStatus(health, maxHealth)
  }
})

// 玩家气血
const playerHealth = () => {
  const { health, maxHealth } = player.value
  return `${Math.max(0, health)} / ${Math.max(0, maxHealth)}`
}

// 怪物气血
const monsterhealth = () => {
  const { health, maxHealth } = monster.value
  return `${Math.max(0, health)} / ${Math.max(0, maxHealth)}`
}

// 动态修改血量状态
const getStatus = (health, maxHealth) => {
  const num = (health / maxHealth) * 100
  return num >= 70 ? 'success' : (num >= 30 ? 'warning' : 'exception')
}

// 生成当前层的怪物
const generateMonster = () => {
  // 根据当前层数计算怪物等级
  const level = currentFloor.value * 2
  const health = monsters.monster_Health(level)
  monster.value = {
    // 名称
    name: monsters.monster_Names(level),
    // 等级
    level,
    // 闪避率
    dodge: monsters.monster_Criticalhitrate(level),
    // 攻击
    attack: monsters.monster_Attack(level),
    // 气血
    health: health,
    // 防御
    defense: monsters.monster_Defense(level),
    // 最大气血
    maxHealth: health,
    // 暴击率
    critical: monsters.monster_Criticalhitrate(level)
  }
  // 日志
  battleLogs.value.push(`你遇到了本层的守护者: ${monster.value.name}`)
}
// 打开双方信息弹窗
const openInfo = (type) => {
  const isPlayer = type == 'player'
  const info = isPlayer ? player.value : monster.value
  ElMessageBox.confirm('', isPlayer ? player.value.name : info.name, {
    center: true,
    message: `<div class="monsterinfo">
      <div class="monsterinfo-box">
      <p>气血: ${formatNumberToChineseUnit(info.health)}</p>
      <p>攻击: ${formatNumberToChineseUnit(info.attack)}</p>
      <p>防御: ${formatNumberToChineseUnit(info.defense)}</p>
      <p>闪避率: ${info.dodge > 0 ? (info.dodge * 100 > 100 ? 100 : (info.dodge * 100).toFixed(2)) : 0}%</p>
      <p>暴击率: ${info.critical > 0 ? (info.critical * 100 > 100 ? 100 : (info.critical * 100).toFixed(2)) : 0}%</p>
      </div>
    </div>`,
    showCancelButton: false,
    confirmButtonText: '知道了',
    dangerouslyUseHTMLString: true
  }).catch(() => { })
}

// 进行战斗
const fight = () => {
  // 被击败
  if (player.value.health <= 0) {
    handlePlayerDefeat()
    return
  }
  // 重新生成新怪物
  if (!monster.value || monster.value.health <= 0) {
    generateMonster()
    return
  }
  // 玩家攻击怪物
  const playerAttackResult = combatSystem.executeCombatRound(player.value, monster.value)
  generateCombatLog(player.value.name, monster.value.name, playerAttackResult)
  // 检查怪物是否被击败
  if (monster.value.health <= 0) {
    handleMonsterDefeat()
    return
  }
  // 怪物攻击玩家
  const monsterAttackResult = combatSystem.executeCombatRound(monster.value, player.value)
  generateCombatLog(monster.value.name, player.value.name, monsterAttackResult)
  // 玩家是否被击败
  if (player.value.health <= 0) {
    handlePlayerDefeat()
  }
}

const generateCombatLog = (attackerName, defenderName, result) => {
  if (!result.isHit) {
    battleLogs.value.push(`${attackerName}的攻击被${defenderName}闪避了。`)
  } else {
    let logMessage = `${attackerName}对${defenderName}造成了${result.damage}点伤害`
    if (result.isCritical) logMessage += '（暴击！）'
    logMessage += `，${defenderName}剩余${result.remainingHealth}气血。`
    battleLogs.value.push(logMessage)
  }
}

// 处理怪物被击败的情况
const handleMonsterDefeat = () => {
  // 修为
  const expGain = Math.floor(monster.value.level * 100)
  // 灵石
  const moneyGain = Math.floor(monster.value.level * 2)
  // 增加修为 
  player.value.cultivation += expGain
  // 增加灵石
  player.value.props.money += moneyGain
  // 日志
  battleLogs.value.push(`你击败了 ${monster.value.name}！`)
  battleLogs.value.push(`获得了 ${expGain}点修为和 ${moneyGain}灵石`)
  // 随机获得装备
  getRandomEquipment()
  // 增加层数
  currentFloor.value++
  // 检查是否是10的倍数层，且之前没有获得过该层的奖励
  if (currentFloor.value % 5 === 0 && !player.value.rewardedTowerFloors.includes(currentFloor.value)) {
    player.value.props.cultivateDan += 500
    player.value.rewardedTowerFloors.push(currentFloor.value)
    battleLogs.value.push(`恭喜你通过第 ${currentFloor.value} 层，获得额外奖励：500培养丹！`)
  }
  // 如果当前层数大于最高层数
  if (currentFloor.value > player.value.highestTowerFloor) player.value.highestTowerFloor = currentFloor.value
  // 日志
  battleLogs.value.push(`成功通过第 ${currentFloor.value - 1} 层，自动前往第 ${currentFloor.value} 层`)
  // 生成新的怪物（下一层）
  generateMonster()
}

// 处理玩家被击败的情况
const handlePlayerDefeat = () => {
  // 日志
  battleLogs.value.push('你被击败了！挑战结束。')
  battleLogs.value.push(`${monster.value.name}: ${boss.drawPrize(monster.value.level).text}`)
  // 关闭自动战斗
  isAutoFighting.value = false
  // 关闭扫荡
  isSweeping.value = false
  // 停止自动战斗
  stopAutoFight()
  // 停止扫荡
  stopSweep()
}
// 切换自动战斗状态
const toggleAutoFight = () => {
  // 切换自动战斗状态
  isAutoFighting.value = !isAutoFighting.value
  // 启动自动战斗
  if (isAutoFighting.value) autoFightInterval.value = setInterval(fight, 1000)
  // 停止自动战斗
  else stopAutoFight()
}

// 停止自动战斗
const stopAutoFight = () => {
  clearInterval(autoFightInterval.value)
  autoFightInterval.value = null
}

// 撤退
const retreat = () => {
  // 关闭自动战斗
  isAutoFighting.value = false
  // 关闭扫荡
  isSweeping.value = false
  // 停止自动战斗
  stopAutoFight()
  // 停止扫荡
  stopSweep()
  router.push('/home')
}

// 随机获得装备
const getRandomEquipment = () => {
  let equipItem = {}
  let exp = Math.floor(player.value.maxCultivation / 100)
  exp = exp ? exp : 1
  const randomInt = equip.getRandomInt(1, 4)
  // 神兵
  if (randomInt == 1) equipItem = equip.equip_Weapons(player.value.level)
  // 护甲
  else if (randomInt == 2) equipItem = equip.equip_Armors(player.value.level)
  // 灵宝
  else if (randomInt == 3) equipItem = equip.equip_Accessorys(player.value.level)
  // 法器
  else if (randomInt == 4) equipItem = equip.equip_Sutras(player.value.level)
  battleLogs.value.push(`你发现了一个宝箱，打开后获得${levels[equipItem.quality]}${equipItem.name}(${genre[equipItem.type]})`)
  // 如果背包满了就不增加装备
  if (player.value.inventory.length >= player.value.backpackCapacity) battleLogs.value.push(`当前装备背包容量已满, 该装备自动丢弃, 转生可增加背包容量`)
  else player.value.inventory.push(equipItem)
}

// 切换扫荡状态
const toggleSweep = () => {
  // 扫荡状态
  isSweeping.value = !isSweeping.value
  if (isSweeping.value) {
    // 重置扫荡时间
    sweepTime.value = 0
    // 重置扫荡结果
    sweepResults.value = { expGain: 0, moneyGain: 0, equipmentGained: 0 }
    // 设定每秒更新扫荡时间
    sweepInterval.value = setInterval(sweep.value, 1000)
    // 每30秒进行一次战斗
    sweepFightInterval.value = setInterval(sweepFight.value, 30000)
  } else {
    // 停止扫荡
    stopSweep()
  }
}

// 停止扫荡
const stopSweep = () => {
  clearInterval(sweepInterval.value)
  clearInterval(sweepFightInterval.value)
  sweepInterval.value = null
  sweepFightInterval.value = null
}

// 进行扫荡
const sweep = () => {
  // 增加扫荡时间
  sweepTime.value++
  // 60秒更新一次日志
  if (sweepTime.value % 60 === 0) battleLogs.value.push(`扫荡结果：目前已扫荡${formatTime(sweepTime.value)}，恭喜你获得了${sweepResults.value.expGain}点修为，${sweepResults.value.moneyGain}灵石和${sweepResults.value.equipmentGained}件装备。`)
}

// 扫荡战斗
const sweepFight = () => {
  // 根据当前层数计算获得经验值
  const expGain = Math.floor(currentFloor.value * 10)
  // 根据当前层数计算获得灵石
  const moneyGain = Math.floor(currentFloor.value * 10)
  // 增加玩家修为
  player.value.cultivation += expGain
  // 增加玩家灵石
  player.value.props.money += moneyGain
  // 增加击杀数
  player.value.jishaNum++
  // 更新扫荡结果中的经验值
  sweepResults.value.expGain += expGain
  // 更新扫荡结果中的灵石
  sweepResults.value.moneyGain += moneyGain
  // 10% 概率获得装备
  const equipmentGained = Math.random() < 0.1
  if (equipmentGained) {
    getRandomEquipment()
    sweepResults.value.equipmentGained++
  }
  // 日志
  battleLogs.value.push(`扫荡结果：恭喜你获得了${expGain}点修为，${moneyGain}块灵石${equipmentGained ? '和1件装备' : '。'}`)
}

const setupObserver = () => {
  const element = scrollbar.value?.wrapRef
  if (element) {
    observer.value = new MutationObserver(() => smoothScrollToBottom(element))
    observer.value.observe(element, { subtree: true, childList: true })
  }
}
const stopObserving = () => {
  if (observer.value) {
    observer.value.disconnect()
    observer.value = null
  }
}

const formatTime = (seconds) => {
  if (seconds < 60) {
    return `${seconds}秒`
  } else if (seconds < 3600) {
    const minutes = Math.floor(seconds / 60)
    const remainingSeconds = seconds % 60
    return `${minutes}分钟${remainingSeconds}秒`
  } else {
    const hours = Math.floor(seconds / 3600)
    seconds %= 3600
    const minutes = Math.floor(seconds / 60)
    const remainingSeconds = seconds % 60
    return `${hours}小时${minutes}分钟${remainingSeconds}秒`
  }
}

onMounted(() => {
  //检查成就
  const newAchievements = checkAchievements(player.value, 'monster')
  newAchievements.forEach(achievement => {
    gameNotifys({
      title: '获得成就提示',
      message: `恭喜你完成了${achievement.name}成就`
    })
  })
  // 当前层数
  currentFloor.value = player.value.highestTowerFloor > 1 ? player.value.highestTowerFloor - 1 : 1
  // 生成日志
  battleLogs.value.push(`欢迎来到无尽塔, 这里是无尽塔的第${currentFloor.value}层, 你的爬塔最高记录为${player.value.highestTowerFloor}层`)
  // 生成怪物
  generateMonster()
})

onUnmounted(() => {
  // 停止自动战斗
  stopAutoFight()
  // 停止扫荡
  stopSweep()
  stopObserving()
})
</script>


<style scoped>
.battle-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.player-info,
.monster-info {
  width: 45%;
}

.name {
  margin-bottom: 10px;
}

.vs {
  font-size: 24px;
  font-weight: bold;
  color: var(--el-color-info);
}

.actions {
  display: flex;
  justify-content: space-between;
  margin: 20px 0;
}

.actions .el-button {
  flex: 1;
  margin: 0 5px;
}

.sweep-info {
  margin: 20px 0;
}

.sweep-info p {
  margin: 5px 0;
  font-size: 14px;
}

.battle-log {
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 5px;
}

.battle-log p {
  margin: 5px 0;
  font-size: 14px;
  color: var(--el-color-info);
}

@media (max-width: 768px) {

  .player-info,
  .monster-info {
    width: 100%;
    margin-bottom: 20px;
  }

  .vs {
    margin: 0 10px;
  }

  .actions {
    flex-wrap: wrap;
  }

  .actions .el-button {
    flex: 1 0 40%;
    margin: 5px;
  }
}
</style>